﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Threading.Tasks;

namespace HongHui_WX.Web.Core.Middleware
{
    /// <summary>
    /// 黑名单中间件，依赖App.User，需放在鉴权、授权之后
    /// </summary>
    public class BlackListMiddleware
    {
        private readonly RequestDelegate _next;
        public IServiceScopeFactory ScopeFactory { get; }

        public BlackListMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)
        {
            _next = next;
            ScopeFactory = scopeFactory;
        }

        public async Task Invoke(HttpContext context)
        {
            var isBlack = await CheckUserIsBlack();

            if (isBlack)
            {
                var response = context.Response;
                response.ContentType = "application/json";
                response.StatusCode = (int)HttpStatusCode.Forbidden;
                await response.WriteAsync(JsonConvert.SerializeObject(new WebPageRespon<string>()
                {
                    Data = "无访问权限",
                    Message = "无访问权限",
                    StatusCode = 2403
                }));
            }
            else
            {
                await _next.Invoke(context);

            }
        }


        /// <summary>
        /// 判断用户是否被拉黑
        /// </summary>
        /// <returns>true:用户被加入黑名单 false:正常用户</returns>
        private async Task<bool> CheckUserIsBlack()
        {
            bool isBlack = false;

            var APPUser = App.User;
            if (APPUser != null && App.User.Claims.Count() > 0 && APPUser.FindFirstValue("userId") != null)
            {
                var userId = APPUser.FindFirstValue("userId");

                var cacheKey = $"black_{userId}";

                if (!string.IsNullOrWhiteSpace(userId))
                {
                    using var scope = ScopeFactory.CreateScope();
                    var _cache = scope.ServiceProvider.GetRequiredService<IMemoryCache>();

                    //是否黑名单用户
                    isBlack = await _cache.GetOrCreateAsync<bool>(cacheKey, async entry =>
                    {
                        //绝对过期时间10分钟
                        if (App.HostEnvironment.IsDevelopment())
                        {
                            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(5);
                        }
                        else
                        {
                            entry.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(600);
                        }

                        using var _scope = ScopeFactory.CreateScope();
                        //获取黑名单逻辑
                        //var _blacklist = _scope.ServiceProvider.GetRequiredService<IRepository<Blacklist>>();
                        //var blackUser = await _blacklist.FirstOrDefaultAsync(s => s.UserID==userId);

                        //if(blackUser != null &&blackUser.UserID>0)
                        //{
                        //    return true;
                        //}
                        return false;
                    });

                    if (isBlack)
                    {
                        $"{cacheKey}:isBlack{isBlack}".LogWarning();
                    }
                }
            }

            return isBlack;
        }
    }
}
